package server;

import com.sun.org.apache.xml.internal.security.Init;
import sun.net.www.http.HttpClient;

import java.io.*;
import java.net.Socket;
import java.time.LocalDate;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * @Description: 单个线程的运行逻辑
 * @Author: ggb
 * @Date: 2021/1/13
 * @Version: 1.0
 */
// 为什么是继承Runnerable而不是另外两种
// Thread类就是实现的Runnable 其次 Future和callable还要以后再讨论
// callable有返回值 而且要配合线程池？
public class TomcatThread implements Runnable {

    // 要保存本线程对应的套接字 及其输入输出流
    private Socket client;
    private InputStream in;
    private OutputStream out;

    // TODO 可以写在文件中
    private static final Map<String, String> contentMap = new HashMap<>();

    static {
        contentMap.put("html", "text/html");
        contentMap.put("htm", "text/html");
        contentMap.put("jpg", "image/jpg");
        contentMap.put("jpeg", "image/jpeg");
        contentMap.put("gif", "image/gif");
        contentMap.put("js", "application/javascript");
        contentMap.put("css", "text/css");
        contentMap.put("json", "application/json");
        contentMap.put("mp3", "audio/mpeg");
        contentMap.put("mp4", "video/mp4");
        contentMap.put("ico", "iamge/avif");
    }

    // 静态文件放在当前文件夹下的static文件夹下
    // TODO 当打包成jar 运行程序放到服务器上之后 怎么去找static的位置？？？ 这个东西不应该依赖具体的业务那边？
    private static String rootPath="";

    static {
        try {
            // TODO 不优雅 还需要改进
            // 编译之后 static文件夹会自动复制到 out/.../static中 秒啊
            rootPath = System.getProperty("user.dir")+"/SecKill/src/static";
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public TomcatThread(Socket client) {
        init(client);
    }

    private void init(Socket client) {
        this.client = client;
        try {
            this.in = client.getInputStream();
            this.out = client.getOutputStream();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @Override
    public void run() {
        try {
            goRun();
        }catch (NullPointerException npe){

        }
        catch (Exception e) {
            e.printStackTrace();
        }
    }

    private void goRun() throws Exception {
        // BufferedReader可以按照换行符 回车符 识别一行一行的数据 因为只读取一行的话比较方便
        BufferedReader reader = new BufferedReader(new InputStreamReader(this.in));
        // TODO 什么叫堵塞的读入？只能读一行？ 只读了第一行
        String originLine = reader.readLine();
        // TODO 为何是先读入一个null 然后再读入GET??
//        System.out.println("读入的这一行是：" + originLine);
        // TODO 为什么是空格之后的第一段？
        String line = originLine.split(" ")[1].replace("/", "\\");;

        // 已经开始路由了
        if (line.equals("\\")) {
            line += "index.html";
        }
//        System.out.println("line最终:" + line);

        String type = line.substring(line.lastIndexOf("."), line.length());

        // TODO 为什么是一个PrintWriter
        PrintWriter writer = new PrintWriter(this.out);
        // TODO 为什么要抽象成inputStream
        InputStream inputStream = new FileInputStream(rootPath + line);

        writer.println("HTTP/1.1 200 ok");
        writer.println("Content-Type: " + contentMap.get(type) + ";charset=utf-8");
        // TODO available???
        writer.println("Content-Length: " + inputStream.available());
        writer.println("Server:hello");
        writer.println("Date: " + LocalDate.now());
        writer.println();
        // TODO flush是干什么
        writer.flush();

        byte[] bytes = new byte[1024];
        int len = 0;
        // TODO 继续读后面的 然后写到输出流？？？？ 这个是从文件读取
        while ((len = inputStream.read(bytes)) != -1) {
            this.out.write(bytes,0,len);
        }
        // TODO 但是关这个writer什么事？？？注册了吗
        writer.flush();

        // TODO in为什么不关闭？？？
//        inputStream.close();
//        writer.close();
//        reader.close();
//        this.out.close();
//        this.client.close();
    }
}
